package com.zyh.scs.admin.controller;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zyh.scs.admin.api.dto.open.TransactionDetailDTO;
import com.zyh.scs.admin.api.dto.open.*;
import com.zyh.scs.admin.api.vo.open.*;
import com.zyh.scs.admin.base.LaoSheFanWeiResponse;
import com.zyh.scs.admin.base.open.*;
import com.zyh.scs.admin.service.UserAccountOpenService;
import com.zyh.scs.admin.service.UserPsnInfoService;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.util.StopWatch;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.List;

/**
 * @author hwh
 * @ClassName: 账户中心开放接口$
 * @Description: $
 * @Date $
 * @Version 1.0
 */
@Slf4j
@RestController
@RequestMapping("/member-center/v1.0/api")
@RequiredArgsConstructor
public class UserAccountOpenController {

    private final UserAccountOpenService userAccountOpenService;

    private final UserPsnInfoService userPsnInfoService;


    /**
     * 校验用户是否有效
     *
     * @param userAccountDto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/account", produces = "application/json;charset=UTF-8")
    public LaoSheCheckResponse<UserAccountVO> checkUserAccount(@RequestBody @Validated UserAccountDto userAccountDto, HttpServletRequest request) {
        log.info("校验用户是否有效 入参:{}", JSON.toJSONString(userAccountDto));
        return userAccountOpenService.checkUserAccount(userAccountDto, request);
    }

    /**
     * 获取个人串码接口
     *
     * @param userPhoneDTO
     * @param request
     * @return
     */
    @PostMapping(value = "/user/send-code", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<String> getUserCode(@RequestBody @Validated UserPhoneDTO userPhoneDTO, HttpServletRequest request) {
        log.info("获取个人串码接口 入参:{}", JSON.toJSONString(userPhoneDTO));
        return userAccountOpenService.getUserCode(userPhoneDTO, request);
    }

    /**
     * 个人码查询用户信息接口
     *
     * @param userCodeDTO
     * @param request
     * @return
     */
    @PostMapping(value = "/user/qrcode-account", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserAccountVO> checkUserAccount(@RequestBody @Validated UserCodeDTO userCodeDTO, HttpServletRequest request) {
        log.info("个人码查询用户信息接口 入参:{}", JSON.toJSONString(userCodeDTO));
        return userAccountOpenService.getCodeToInfo(userCodeDTO, request);
    }

    /**
     * 获取token
     *
     * @param userPhoneDTO
     * @param request
     * @return
     */
    @PostMapping(value = "/user/send-token", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<String> sendToken(@RequestBody @Validated UserPhoneDTO userPhoneDTO, HttpServletRequest request) {
        log.info("获取token 入参:{}", JSON.toJSONString(userPhoneDTO));
        return userAccountOpenService.sendToken(userPhoneDTO.getUserPhone(), request);
    }

    /**
     * 通过token获取用户信息
     *
     * @param userTokenDTO
     * @param request
     * @return
     */
    @PostMapping(value = "/user/token", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserAccountVO> queryAccountByToken(@RequestBody @Validated UserTokenDTO userTokenDTO, HttpServletRequest request) {
        log.info("通过token获取用户信息 入参:{}", JSON.toJSONString(userTokenDTO));
        return userAccountOpenService.queryAccountByToken(userTokenDTO.getUserToken(), request);
    }

    /**
     * 查询用户分页列表接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/account-pagelist", produces = "application/json;charset=UTF-8")
    public LaoSheAccountTotalResponse<List<UserAccountVO>> userAccountPageList(@RequestBody @Validated UserAccountPageDTO dto, HttpServletRequest request) {
        log.info("查询用户分页列表接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.userAccountPageList(dto, request);
    }

    /**
     * 用户信息同步接口
     * <p>
     * TODO 调满客宝的接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/account-sync", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<String> userAccountSync(@RequestBody @Validated UserSyncDTO dto, HttpServletRequest request) {
        log.info("用户信息同步接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.userAccountSync(dto, request);
    }

    /**
     * 机构信息同步接口
     * <p>
     * TODO 调满客宝的接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/dept-sync", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<String> userDeptSync(@RequestBody @Validated DeptSyncDTO dto, HttpServletRequest request) {
        log.info("机构信息同步接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.userDeptSync(dto, request);
    }

    /**
     * 订单扣费接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/order/deduction", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserDeductionVO> orderRefund(@RequestBody @Validated UserDeductionDTO dto, HttpServletRequest request) {
        log.info("订单扣费接口 入参:{}", JSON.toJSONString(dto));
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("订单扣减");
        final LaoSheResponse<UserDeductionVO> deduction = userAccountOpenService.deduction(dto, request);
        stopWatch.stop();
        log.info("订单扣减整体耗时打印：{}", stopWatch.prettyPrint());
        return deduction;
    }


    /**
     * 支付码扣费接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/order/qrcode-deduction", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserDeductionVO> qrCodeDeduction(@RequestBody @Validated QrCodeDeductionDTO dto, HttpServletRequest request) {
        log.info("支付码扣费接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.qrCodeDeduction(dto, request);
    }


    /**
     * 交易流水查询
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/pay/flow/detail", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<TransactionDetailVO> transactionDetail(@RequestBody @Validated TransactionDetailDTO dto, HttpServletRequest request) {
        log.info("交易流水查询 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.transactionDetail(dto, request);
    }


    /**
     * 充值流水查询接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/pay", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<TransactionDetailVO> payDetail(@RequestBody @Validated TransactionDetailDTO dto, HttpServletRequest request) {
        log.info("充值流水查询接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.payDetail(dto, request);
    }


    /**
     * 订单查询接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/order/detail", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<OrderDetailVO> detail(@RequestBody @Validated OrderDetailDTO dto, HttpServletRequest request) {
        log.info("订单查询接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.detail(dto, request);
    }

    /**
     * 交易流水查询接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/pay/flow/detail", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<TransactionDetailVO> transactionFlow(@RequestBody @Validated TransactionDetailDTO dto, HttpServletRequest request) {
        log.info("交易流水查询接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.transactionFlow(dto, request);
    }

    /**
     * 交易流水查询接口 (好店专用)
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "user/account-transaction-flow", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<Page<TransactionFlowVO>> transactionFlowHaoDian(@RequestBody @Validated TransactionFlowDTO dto, HttpServletRequest request) {
        log.info("交易流水查询接口 (好店专用) 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.transactionFlowHaoDian(dto, request);
    }

    /**
     * 充值流水查询接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/recharge/flow/detail", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<RechargeFlowDetailVO> rechargeFlowDetail(@RequestBody @Validated TransactionDetailDTO dto, HttpServletRequest request) {
        log.info("充值流水查询接口  入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.rechargeFlowDetail(dto, request);
    }

    /**
     * 订单退款接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/order/refund", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<OrderInfoExDto> orderRefund(@RequestBody @Validated OrderRefundDTO dto, HttpServletRequest request) {
        log.info("订单退款接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.orderRefund(dto, request);
    }


    /**
     * 订单撤销接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/order/cancel", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<OrderInfoExDto> cancel(@RequestBody @Validated OrderCancelDTO dto, HttpServletRequest request) {
        log.info("订单撤销接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.cancel(dto, request);
    }


    /**
     * 绑卡/解绑接口(用于线上操作，福利卡账户绑定)
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/bind-card", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserBindCardVO> bindCard(@RequestBody @Validated UserBindDTO dto, HttpServletRequest request) {
        log.info("绑卡/解绑接口(用于线上操作，福利卡账户绑定) 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.bindCard(dto, request);
    }

    /**
     * 物理卡信息同步接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/sync-cardid", produces = "application/json;charset=UTF-8")
    public LaoSheDateResponse<String> syncCardId(@RequestBody @Validated SyncCardIdDTO dto, HttpServletRequest request) {
        log.info("物理卡信息同步接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.syncCardId(dto, request);
    }

    /**
     * 新增编外员工接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/add-extraStaff", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserGuidVO> addExtraStaff(@RequestBody @Validated UserAddExtraStaffDTO dto, HttpServletRequest request) {
        log.info("新增编外员工接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.addExtraStaff(dto, request);
    }

    /**
     * 新增/修改编外机构信息接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/external-dept/sync", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<UserDeptIdVO> syncExternalDepartment(@RequestBody @Validated SyncExtDepartmentDTO dto, HttpServletRequest request) {
        log.info("新增/修改编外机构信息接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.syncExternalDepartment(dto, request);
    }


    /**
     * 物理卡/福利账户充值接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/sync-recharge", produces = "application/json;charset=UTF-8")
    public LaoSheDateResponse<String> syncCardIdRecharge(@RequestBody @Validated CardIdRechargeDTO dto, HttpServletRequest request) {
        log.info("物理卡/福利账户充值接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.syncCardIdRecharge(dto, request);
    }


    /**
     * 物理卡/福利账户批量充值接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/batch-recharge", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<List<String>> batchRecharge(@RequestBody @Validated CardIdBatchRechargeDTO dto, HttpServletRequest request) {
        log.info("物理卡/福利账户批量充值接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.batchRecharge(dto, request);
    }

    /**
     * 现金账户充值接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/cash-recharge", produces = "application/json;charset=UTF-8")
    public LaoSheTimeResponse<String> syncCashRecharge(@RequestBody @Validated CashRechargeDTO dto, HttpServletRequest request) {
        log.info("现金账户充值接口 入参:{}", JSON.toJSONString(dto));
        StopWatch stopWatch = new StopWatch();
        stopWatch.start("现金充值");
        final LaoSheTimeResponse<String> stringLaoSheTimeResponse = userAccountOpenService.syncCashRecharge(dto, request);
        stopWatch.stop();
        log.info("现金充值整体耗时打印：{}", stopWatch.prettyPrint());
        return stringLaoSheTimeResponse;
    }

    /**
     * 物理卡解绑操作
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/cardid-unbound", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<String> cardIdUnbound(@RequestBody @Validated UserCardIdUnboundDTO dto, HttpServletRequest request) {
        log.info("物理卡解绑操作 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.cardIdUnbound(dto, request);
    }

    /**
     * 见习转正接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/change-to-normal", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<ChangeToNormalVO> changeToStaff(@RequestBody @Validated ChangeToNormalDTO dto, HttpServletRequest request) {
        log.info("见习转正接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.changeToStaff(dto, request);
    }


    /**
     * 福利卡/现金账户充值撤销接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/recharge-rollback", produces = "application/json;charset=UTF-8")
    public LaoSheCallResponse<String> rollBackRecharge(@RequestBody @Validated RollBackRechargeDTO dto, HttpServletRequest request) {
        log.info("福利卡/现金账户充值撤销接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.rollBackRecharge(dto, request);
    }

    /**
     * 福利卡/现金账户提现接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/account-withdrawal", produces = "application/json;charset=UTF-8")
    public LaoSheCallResponse<String> withdrawal(@RequestBody @Validated WithdrawalDTO dto, HttpServletRequest request) {
        log.info("福利卡/现金账户提现接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.withdrawal(dto, request);
    }

    /**
     * 注册回调接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/callback/register", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<OrderDeductionVO> register(@RequestBody @Validated CallbackUrlDTO dto, HttpServletRequest request) {
        log.info("注册回调接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.register(dto, request);
    }

    /**
     * 报表接口
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/finance/list", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<List<FinanceVO>> financeList(@RequestBody @Validated FinanceDTO dto, HttpServletRequest request) {
        log.info("报表接口 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.financeList(dto, request);
    }

    /**
     * 冻结/解冻
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/freezeOperate", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<String> freezeOperate(@RequestBody @Validated UserFreezeDTO dto, HttpServletRequest request) {
        log.info("冻结/解冻 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.freezeOperate(dto, request);
    }

    /**
     * 用户有效性校验
     *
     * @param dto
     * @param request
     * @return
     */
    @PostMapping(value = "/user/check", produces = "application/json;charset=UTF-8")
    public com.zyh.scs.admin.base.open.LaoSheResponse<Integer> userCheck(@RequestBody @Validated UserCheckDTO dto, HttpServletRequest request) {
        log.info("用户有效性校验 入参:{}", JSON.toJSONString(dto));
        return userAccountOpenService.userCheck(dto, request);
    }

    /**
     * 推送人员到满客宝
     *
     * @return
     */
    @Operation(summary = "推送人员到满客宝", description = "推送人员到满客宝")
    @GetMapping(value = "/user/push", produces = "application/json;charset=UTF-8")
    public LaoSheFanWeiResponse pushUser() {
        userPsnInfoService.pushDepartment();
        return userPsnInfoService.pushUser();
    }

    /**
     * 推送人员到满客宝
     *
     * @return
     */
    @Operation(summary = "推送人员到满客宝", description = "推送人员到满客宝")
    @GetMapping(value = "/user/pull", produces = "application/json;charset=UTF-8")
    public boolean pull() {
        return userPsnInfoService.pull();
    }

    /**
     * 通过 部门id 推送部门到满客宝
     *
     * @return
     */
    @Operation(summary = "通过 部门id推送人员到满客宝", description = "通过 部门id推送人员到满客宝")
    @GetMapping(value = "/user/push/deptId", produces = "application/json;charset=UTF-8")
    public LaoSheFanWeiResponse pushDept(String deptId) {
        return userPsnInfoService.pushDeptId(deptId);
    }

    /**
     * 通过 用户id 推送人员到满客宝
     *
     * @return
     */
    @Operation(summary = "通过 用户id推送人员到满客宝", description = "通过 用户id推送人员到满客宝")
    @GetMapping(value = "/user/push/user", produces = "application/json;charset=UTF-8")
    public LaoSheFanWeiResponse pushUser(String guid) {
        return userPsnInfoService.pushUser(guid);
    }
}
